package com.android.dopewars;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Vector;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TextView;

import com.android.dopewars.DealerEdit;

public class DopeWars extends Activity {

	public static final int PLAY_GAME_30 = 1000;
	public static final int PLAY_GAME_60 = 1001;
	public static final int PLAY_GAME_HUSTLER_30 = 1002;
	public static final int PLAY_GAME_HUSTLER_60 = 1003;
	
	public static String gameModeString(int game_mode) {
		switch(game_mode) {
		case PLAY_GAME_30:
			return "30-day-3";
		case PLAY_GAME_60:
			return "60-day-3";
		case PLAY_GAME_HUSTLER_30:
			return "30-day-hustler";
		case PLAY_GAME_HUSTLER_60:
			return "60-day-hustler";
		}
		return "";
	}
	public static final int EDIT_DEALER = 1;
	public static final int HIGH_SCORES = 4;
	public static final int GLOBAL_HIGH_SCORES = 5;
	public static final int HIGH_SCORE_INFO = 6;
	public static final int NEW_USER_EVENT = 7;
	
	// Listen for a click on the edit dealer button. When the button is clicked, the global
	// dealer is set to the currently selected dealer, and the edit dealer dialog
	// is started. The edit dealer dialog will do its editing on whatever the current
	// global dealer is set to.
	public class EditListener implements View.OnClickListener {
		public void onClick(View v) {
			// Need to determine the dealer that's been selected.
    		String dealer_name = (String)((Spinner)findViewById(R.id.dealer_choice)).getSelectedItem();
    		Global.dealer_ = Global.dealers_.elementAt(0);
    		for (int j = 0; j < Global.dealers_.size(); ++j) {
    			if (dealer_name.equals(Global.dealers_.elementAt(j).name())) {
    				Global.dealer_ = Global.dealers_.elementAt(j);
    			}
    		}
    		
    		Intent i = new Intent(v.getContext(), DealerEdit.class);
       		startActivityForResult(i, EDIT_DEALER);
		}
	}
	
	public class NewDealerListener implements View.OnClickListener {
		public void onClick(View v) {
			Global.dealer_ = new Dealer("New Baker " + Integer.toString(
       				Global.dealers_.size() + 1), true);
       		Global.dealers_.add(Global.dealer_);
       		Intent i = new Intent(v.getContext(), DealerEdit.class);
       		startActivityForResult(i, EDIT_DEALER);
		}
	}
	
	public class GameStartListener implements View.OnClickListener {
		public GameStartListener(int game_length, boolean hustler_mode, int result_code) {
			game_length_ = game_length;
			hustler_mode_ = hustler_mode;
			result_code_ = result_code;
		}
		public void onClick(View v) {
    		Intent i = new Intent(v.getContext(), DrugBuySell.class);
    		
    		// Need to determine the dealer that's been selected.
    		String dealer_name = (String)((Spinner)findViewById(R.id.dealer_choice)).getSelectedItem();
    		Global.dealer_ = Global.dealers_.elementAt(0);
    		for (int j = 0; j < Global.dealers_.size(); ++j) {
    			if (dealer_name.equals(Global.dealers_.elementAt(j).name())) {
    				Global.dealer_ = Global.dealers_.elementAt(j);
    			}
    		}
    		Global.dealer_.reset_highest_cash_amount();
    		if (hustler_mode_) {
    			Global.dealer_.setCash(50000000);
    		}
    		Global.dealer_.setCash(3000);
    		Global.dealer_.setDebt(5500);
    		Global.dealer_.setBank(0);
    		Global.dealer_.setTotalSpace(100);
    		Global.dealer_.setHealth(100);
    		Global.dealer_.removeAllInventory();
    		Global.unstockStore();
    		Global.maximum_loan_amount_ = hustler_mode_ ? 2500000 : 100000;
    		Global.days_left_ = game_length_;
    		Global.total_days_ = Global.days_left_;
    		Global.first_day_ = true;
    		Global.location_ = 0;
    		
       		startActivityForResult(i, result_code_);
		}
		
		private int game_length_;
		private boolean hustler_mode_;
		private int result_code_;
	}
	
	public class LocalHighScoreListener implements View.OnClickListener {
		public LocalHighScoreListener(int game_mode) {
			game_mode_ = game_mode;
		}
		
       	public void onClick(View v) {
       		Intent i = new Intent(v.getContext(), HighScores.class);
       		
       	    // Need to determine the dealer that's been selected.
    		String dealer_name = (String)((Spinner)findViewById(R.id.dealer_choice)).getSelectedItem();
    		Global.dealer_ = Global.dealers_.elementAt(0);
    		for (int j = 0; j < Global.dealers_.size(); ++j) {
    			if (dealer_name.equals(Global.dealers_.elementAt(j).name())) {
    				Global.dealer_ = Global.dealers_.elementAt(j);
    			}
    		}
    		Vector<String> score_list_names = new Vector<String>();
    		Vector<Integer> score_list_scores = new Vector<Integer>();

    		for (int d = 0; d < Global.dealers_.size(); ++d) {
    			Vector<Integer> mode_scores = Global.dealers_.elementAt(d).gameScores(game_mode_);
    			if (mode_scores != null) {
    				for (int s = 0; s < mode_scores.size(); ++s) {
    					int insert_point = 0;
    					while (score_list_scores.size() > insert_point) {
    						if (score_list_scores.elementAt(insert_point) < mode_scores.elementAt(s)) {
    							break;
    						}
    						++insert_point;
    					}
    					if (insert_point < 100) {
    						if (insert_point == score_list_scores.size()) {
    							score_list_names.add(Global.dealers_.elementAt(d).name());
    							score_list_scores.add(mode_scores.elementAt(s));
    						} else {
    							score_list_names.insertElementAt(Global.dealers_.elementAt(d).name(), insert_point);
    							score_list_scores.insertElementAt(mode_scores.elementAt(s), insert_point);
    						}
    					}
    				}
       			}
       		}

    		Global.high_score_list_names_.clear();
    		Global.high_score_list_scores_.clear();
    		Global.high_score_list_dates_.clear();
    		Global.high_score_list_comments_.clear();
    		
    		for (int j = 0; j < score_list_scores.size(); ++j) {
       			Global.high_score_list_names_.add(score_list_names.elementAt(j));
       			Global.high_score_list_scores_.add(Integer.toString(score_list_scores.elementAt(j)));
       			Global.high_score_list_dates_.add("");
       			Global.high_score_list_comments_.add("");
       		}
       		startActivityForResult(i, HIGH_SCORES);
       	}
       	
       	int game_mode_;
    }
	
	public class GlobalHighScoreListener implements View.OnClickListener {
		public GlobalHighScoreListener(int game_mode) {
			game_mode_ = game_mode;
		}
		
       	public void onClick(View v) {
       		Intent i = new Intent(v.getContext(), HighScores.class);
       		try {
       			String get_raw_high_scores_string = "http://dopewars-highscores.appspot.com/high_scores_raw?game_mode=" + gameModeString(game_mode_);
	    		HttpURLConnection conn = (HttpURLConnection) (new URL(get_raw_high_scores_string)).openConnection();
	    		conn.setDoInput(true);
	    		conn.setDoOutput(true);
	    		conn.connect();
	    		int response_code = conn.getResponseCode();
	    		if (response_code == -1) {
	    			get_raw_high_scores_string = "";
	    		}
	    	    String string;
	    	    if (conn.getInputStream() != null) {
	    	        BufferedReader reader = new BufferedReader(new InputStreamReader(
	    	        		conn.getInputStream()));
	        		Global.high_score_list_names_.clear();
	        		Global.high_score_list_scores_.clear();
	        		Global.high_score_list_dates_.clear();
	        		Global.high_score_list_comments_.clear();
	    	        int score_number = 1;
	    	        while (null != (string = reader.readLine())) {
	    	        	String[] pieces = string.split(",",4);
	    	        	if (pieces.length == 4) {
	    	        		Global.high_score_list_names_.add(pieces[0]);
	    	       			Global.high_score_list_scores_.add(pieces[1]);
	    	       			Global.high_score_list_dates_.add(pieces[2]);
	    	       			Global.high_score_list_comments_.add(pieces[3]);
	    	        		score_number++;
	    	        	}
	    	        }
	    	    }
	    	    conn.disconnect();
	    		
    		} catch (IOException e) {
    			i.putExtra("high_score_1_name", "Network Error");
    			i.putExtra("high_score_1_score", "0");
    		}
       		startActivityForResult(i, HIGH_SCORES);
       	}
       	
       	int game_mode_;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        // Set up the main content of the view. This layout includes creating and editing dealers, which are
        // the characters in the game, starting the different game modes, and viewing high scores.
        // It is considered the "home screen" and is the first thing you see when you open the game.
        setContentView(R.layout.main_menu);
        
        // Set up the button listeners for dealer creation and editing.
        ((Button)findViewById(R.id.edit_dealer_button)).setOnClickListener(new EditListener());
        ((Button)findViewById(R.id.new_dealer_button)).setOnClickListener(new NewDealerListener());
        
        ((Button)findViewById(R.id.classic_mode_start)).setOnClickListener(new GameStartListener(30, false, PLAY_GAME_30));
        ((Button)findViewById(R.id.extended_mode_start)).setOnClickListener(new GameStartListener(60, false, PLAY_GAME_60));
        ((Button)findViewById(R.id.hustler_mode_start)).setOnClickListener(new GameStartListener(30, true, PLAY_GAME_HUSTLER_30));
        ((Button)findViewById(R.id.extended_hustler_mode_start)).setOnClickListener(new GameStartListener(60, true, PLAY_GAME_HUSTLER_60));
        
        ((Button)findViewById(R.id.classic_mode_local_high_scores)).setOnClickListener(new LocalHighScoreListener(PLAY_GAME_30));
        ((Button)findViewById(R.id.extended_mode_local_high_scores)).setOnClickListener(new LocalHighScoreListener(PLAY_GAME_60));
        ((Button)findViewById(R.id.hustler_mode_local_high_scores)).setOnClickListener(new LocalHighScoreListener(PLAY_GAME_HUSTLER_30));
        ((Button)findViewById(R.id.extended_hustler_mode_local_high_scores)).setOnClickListener(new LocalHighScoreListener(PLAY_GAME_HUSTLER_60));
        
        ((Button)findViewById(R.id.classic_mode_global_high_scores)).setOnClickListener(new GlobalHighScoreListener(PLAY_GAME_30));
        ((Button)findViewById(R.id.extended_mode_global_high_scores)).setOnClickListener(new GlobalHighScoreListener(PLAY_GAME_60));
        ((Button)findViewById(R.id.hustler_mode_global_high_scores)).setOnClickListener(new GlobalHighScoreListener(PLAY_GAME_HUSTLER_30));
        ((Button)findViewById(R.id.extended_hustler_mode_global_high_scores)).setOnClickListener(new GlobalHighScoreListener(PLAY_GAME_HUSTLER_60));

        
        // Static game stuff, hard-coded but needs to be "loaded"
        Global.setupDrugs();
        Global.setupGuns();
        Global.setupBags();
        Global.setupRandomMessages();
        Global.setupSongs();
        
        // Dynamic game stuff, loaded once at game start.
        loadSavedDealers();
        
        // The final score is always visible because the space it takes up pleases me, but it is empty
        // when the game is first created.
        ((TextView)findViewById(R.id.last_game_score)).setText(" ");
        
        // Setup the choices for what dealers exist, and hide interface elements that may not be applicable.
        setupDealers();
    }
    
    @Override
    public void onStop() {
    	super.onStop();
    	saveDealers();
    } 
    
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
    	super.onActivityResult(requestCode, resultCode, intent);
    	
    	switch(requestCode) {
    	
    	// the user possibly edited a dealer. save the dealers to persistent storage, and update the 
    	// displayed dealers
    	case EDIT_DEALER:
    		saveDealers();
    		setupDealers();
    		break;
    	case PLAY_GAME_30:
    	case PLAY_GAME_60:
    	case PLAY_GAME_HUSTLER_30:
    	case PLAY_GAME_HUSTLER_60:
    	{
    		int game_score = Global.dealer_.cash() + Global.dealer_.bank() - Global.dealer_.debt();
    		Global.dealer_.addGameScore(requestCode, game_score);
    		((TextView)findViewById(R.id.last_game_score)).setText("Final score: $" + Integer.toString(game_score));
    		String is_high_score_url_string = "http://dopewars-highscores.appspot.com/is_high_score?game_mode=" +
    			gameModeString(requestCode) + "&new_score=" + Integer.toString(game_score);
    		try {
    			HttpURLConnection conn = (HttpURLConnection) (new URL(is_high_score_url_string)).openConnection();
    			conn.setDoInput(true);
    			conn.setDoOutput(true);
    			conn.connect();
    			String response = Global.connectionToString(conn.getInputStream());
    			conn.disconnect();
    			if (response.equals("yes\n")) {
    				Global.high_score_name_ = Global.dealer_.name();
    				Global.high_score_comment_ = "no comment";
    				Global.high_score_mode_ = gameModeString(requestCode);
    				Global.high_score_ = game_score;
    				Intent i = new Intent(this, HighScoreInfo.class);
    				startActivityForResult(i, HIGH_SCORE_INFO);
    			}
    		} catch (IOException e) {
    		}
    		
    		// check for entering a new user event
    		double new_user_event = Global.rand_gen_.nextDouble();
    		if (new_user_event < 0.02) {
    			Intent i = new Intent(this, NewUserEvent.class);
    			startActivityForResult(i, NEW_USER_EVENT);
    		}
    		saveDealers();
            setupDealers();
    		break;
    	}
    	case NEW_USER_EVENT:
    	{
    		if ((Global.new_user_event_player_.length() > 0) &&
    				(Global.new_user_event_.length() > 0)) {
	    		String new_user_event_string = "http://dopewars-highscores.appspot.com/add_user_event?password=<redacted>&player_name=" +
						Uri.encode(Global.new_user_event_player_) + "&new_event=" + 
						Uri.encode(Global.new_user_event_);
	    		try {
	    			HttpURLConnection conn2 = (HttpURLConnection) (new URL(new_user_event_string)).openConnection();
	    			conn2.setDoInput(true);
	    			conn2.setDoOutput(true);
	    			conn2.connect();
	    			Global.connectionToString(conn2.getInputStream());
	    			conn2.disconnect();
	    		} catch (IOException e) {
	    		}
    		}
    	break;
    	}
    	case HIGH_SCORE_INFO:
    	{
    		String enter_high_score_url_string = "http://dopewars-highscores.appspot.com/enter_high_score?password=<redacted>&game_mode=" +
    				Global.high_score_mode_ + "&new_score=" + Integer.toString(Global.high_score_) + "&player_name=" +
    				Uri.encode(Global.high_score_name_) + "&player_comment=" + Uri.encode(Global.high_score_comment_);
    		try {
	    		HttpURLConnection conn2 = (HttpURLConnection) (new URL(enter_high_score_url_string)).openConnection();
	    		conn2.setDoInput(true);
	    		conn2.setDoOutput(true);
	    		conn2.connect();
	    		String response2 = Global.connectionToString(conn2.getInputStream());
	    		conn2.disconnect();
	    		if (response2.substring(0, 7).equals("success")) {
	    			// get the number to highlight
	    			String pos_string = response2.substring(8).substring(0, response2.length() - 9);
	    			int position = Integer.valueOf(pos_string);
	    			Intent i = new Intent(this, HighScores.class);
           			String get_raw_high_scores_string = "http://dopewars-highscores.appspot.com/high_scores_raw?game_mode=" + Global.high_score_mode_;
		    		HttpURLConnection conn = (HttpURLConnection) (new URL(get_raw_high_scores_string)).openConnection();
		    		conn.setDoInput(true);
		    		conn.setDoOutput(true);
		    		conn.connect();
		    		int response_code = conn.getResponseCode();
		    		if (response_code == -1) {
		    			get_raw_high_scores_string = "";
		    		}
		    	    String string;
		    	    if (conn.getInputStream() != null) {
		    	        BufferedReader reader = new BufferedReader(new InputStreamReader(
		    	        		conn.getInputStream()));
		    	        
		    	        Global.high_score_list_names_.clear();
		        		Global.high_score_list_scores_.clear();
		        		Global.high_score_list_dates_.clear();
		        		Global.high_score_list_comments_.clear();
		        		
		    	        while (null != (string = reader.readLine())) {
		    	        	String[] pieces = string.split(",");
		    	        	if (pieces.length == 4) {
		    	        		Global.high_score_list_names_.add(pieces[0]);
		    	        		Global.high_score_list_scores_.add(pieces[1]);
			           			Global.high_score_list_dates_.add(pieces[2]);
			           			Global.high_score_list_comments_.add(pieces[3]);
		    	        	}
		           		}
		    	        Global.high_score_list_row_to_highlight_ = position - 1;
		    	    }
		    	    conn.disconnect();
		    	    startActivityForResult(i, HIGH_SCORES);
	    		}
	    	} catch (IOException e) {
	    	}
    		break;
    	}
		}
    	
    }
    
    // Setup dealers will populate the spinner with the names of the available dealers. It will also
    // hide the "New Dealer" button if there are already three dealers in existence.
    public void setupDealers() {
		String[] dealer_names = new String[Global.dealers_.size()];
		int index = 0;
		if (Global.dealer_ != null) {
			dealer_names[0] = Global.dealer_.name();
			index = 1;
		}
		for (int i = 0; i < Global.dealers_.size(); ++i) {
			if (Global.dealer_ != Global.dealers_.elementAt(i)) {
				dealer_names[index++] = Global.dealers_.elementAt(i).name();
			}
		}
    	ArrayAdapter<String> dealer_adapter = new ArrayAdapter<String>(
    			this, android.R.layout.simple_spinner_item, dealer_names);
    	((Spinner)findViewById(R.id.dealer_choice)).setAdapter(dealer_adapter);
    	findViewById(R.id.edit_dealer_button).setVisibility(
    			Global.dealers_.size() > 0 ? View.VISIBLE : View.GONE);
    	findViewById(R.id.new_dealer_button).setVisibility(
    			Global.dealers_.size() < 3 ? View.VISIBLE : View.GONE);
    	
    	// Hide the game buttons if no dealers exist.
    	findViewById(R.id.classic_mode).setVisibility(Global.dealers_.size() == 0 ? View.GONE : View.VISIBLE);
    	findViewById(R.id.extended_mode).setVisibility(Global.dealers_.size() == 0 ? View.GONE : View.VISIBLE);
    	findViewById(R.id.hustler_mode).setVisibility(Global.dealers_.size() == 0 ? View.GONE : View.VISIBLE);
    	findViewById(R.id.extended_hustler_mode).setVisibility(Global.dealers_.size() == 0 ? View.GONE : View.VISIBLE);
    }
    
    public void loadSavedDealers() {
    	try {
    		BufferedReader dealer_save_file = new BufferedReader(
    				new InputStreamReader(openFileInput("dopewars_dealers")));
    		if (dealer_save_file != null) {
	    		String next_line = dealer_save_file.readLine();
	    		Global.dealers_ = new Vector<Dealer>();
	    		while ((next_line != null) && (next_line.length() > 0)) {
	    			Global.dealers_.add(new Dealer(next_line));
	    			next_line = dealer_save_file.readLine();
	    		}
	    		dealer_save_file.close();
	    		Global.dealer_ = null;
    		}
    	} catch (FileNotFoundException e) {
    	} catch (IOException e) {
    	} catch (Exception e) {
    	}
    }
    
    public void saveDealers() {
    	try {
    		BufferedWriter dealer_save_file = new BufferedWriter(
    				new OutputStreamWriter(openFileOutput("dopewars_dealers", 0)));
    		if (dealer_save_file != null) {
    			for (int i = 0; i < Global.dealers_.size(); ++i) {
    				dealer_save_file.write(Global.dealers_.elementAt(i).toString() + "\n");
    			}
    			dealer_save_file.flush();
    			dealer_save_file.close();
    		}
    	} catch (FileNotFoundException e) {
    	} catch (IOException e) {
    	} catch (Exception e) {
    	}
    }
    
    
}